<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      .box {
        width: 100px;
        height: 100px;
        background-color: brown;
        position: absolute;
        top: 30px;
        left: 100px;
        /* transition: all 1s; */
      }
    </style>
  </head>
  <body>
    <div id="box" class="box"></div>
    <script>
      //   编写动画函数animate duration:持续事件
      function animate(ele, targetCssObj, duration, callback) {
        var interval = 20 // 每20ms移动一次
        var moveTotalCount = duration / interval // 移动的总次数
        console.log('moveTotalCount:', moveTotalCount)
        var timer
        // 得到元素ele最初始化的位置信息
        var initCssStyle = {}
        for (var cssKey in targetCssObj) {
          initCssStyle[cssKey] = parseInt(
            window.getComputedStyle(ele, null)[cssKey]
          )
        }

        // 把初始对象initCssStyle拷贝一份，后面使用到
        // var copyInitCssStyle = {}
        // for (var cssKey in initCssStyle) {
        //   copyInitCssStyle[cssKey] = initCssStyle[cssKey]
        // }

        // 定时器，每隔20ms移动指定的像素位置
        var count = 0
        timer = setInterval(function () {
          count++
          // 计算出每次移动的距离：（终点位置-起点（初始）位置） / 总移动的次数
          for (var cssKey in targetCssObj) {
            var stepMove =
              (targetCssObj[cssKey] - initCssStyle[cssKey]) / moveTotalCount
            // 开始移动起来
            ele.style[cssKey] = initCssStyle[cssKey] + stepMove * count + 'px'
          }

          // 到达了总次数，则停止移动
          if (count >= moveTotalCount) {
            clearInterval(timer)
            // 强制拉回到终点位置，避免小数的误差
            for (var cssKey in targetCssObj) {
              ele.style[cssKey] = targetCssObj[cssKey] + 'px'
            }
            // 若用户传递回调则执行，没传就不执行
            callback && callback()
          }
        }, interval)
      }

      var boxEle = document.getElementById('box')

      boxEle.addEventListener('click', function () {
        animate(boxEle, { left: 300, top: 400 }, 1999, function () {
          console.log('动画结束了')
        })
      })
    </script>
  </body>
</html>
